from google.appengine.txt import db

# ===========================================================================
class Person(db.Model):
    """
    A person, a group member or leader.
    """
    p_firstname = db.StringProperty()
    p_lastname = db.StringProperty()
    p_phone = db.PhoneNumberProperty()
    p_email = db.EmailProperty()
    p_username = db.StringProperty()
    p_role = db.StringListProperty()
    
    # p_adder = db.UserProperty(auto_current_user_add=True)
    # p_added = db.DateTimeProperty(auto_now_add=True)
    p_updater = db.UserProperty(auto_current_user=True)
    p_updated = db.DateTimeProperty(auto_now=True)

# ===========================================================================
class PersonPage(GenericPage):
    """
    supported URLs:
    .../person                 => list all Person records
    .../person/new             => create new Person record
    .../person/view?id=<id>    => display Person <id>
    .../person/update?id=<id>  => update Person <id>
    .../person/delete?id=<id>  => delete Person <id>
    """
    # ----------------------------------------------------------------------
    def get(self):
        if not users.is_current_user_admin():
            self.redirect("/")

        domain = self.get_domain()
        action = self.get_action()

        which = self.request.get('id')
        if domain != 'person':
            self.add_error('Wrong domain')
        if action not in ['list', 'new', 'view', 'update', 'delete']:
            self.add_error('Invalid action: %s' % action)
        if action in ['view', 'update', 'delete'] and which == '':
            self.add_error('Action %s requires a person id' % action)

        # logging.info('in get(2): action = %s' % self.request.get('action'))
        
        if action == 'list':
            plist = []
            for p in Person.all():
                p.p_updated = eastern_time(p.p_updated)
                rlist = [str(role) for role in p.p_role]
                p.p_role = rlist
                plist.append(p)
                
            template_values = {
                'action': action,
                'errors': self.get_errors(),
                'plist': plist,
                }
            template = jinja_environment.get_template('person.html')
            self.response.out.write(template.render(template_values))
        elif action == 'new':
            plist = []
            cache = self.get_cache()
            logging.info('PersonPage.get - retrieved cache: %s'
                         % cache)
            template_values = {
                'errors': self.get_errors(),
                'cache': cache,
                'action': action,
                }
            template = jinja_environment.get_template('person.html')
            self.response.out.write(template.render(template_values))
        elif action == 'update':
            pid = self.request.get('id')
            plist = [ Person.get_by_id(int(pid)) ]
            cache = self.get_cache()
            logging.info('PersonPage.get - cache: %s' % cache)
            template_values = {
                'action': action,
                'cache': cache,
                'errors': self.get_errors(),
                'id': pid,
                }
            template = jinja_environment.get_template('person.html')
            self.response.out.write(template.render(template_values))
        elif action == 'delete':
            pid = self.request.get('id')
            plist = [ Person.get_by_id(int(pid)) ]
            template_values = {
                'action': action,
                'cache': self.get_cache(),
                'errors': self.get_errors(),
                'id': pid,
                }
            template = jinja_environment.get_template('person.html')
            self.response.out.write(template.render(template_values))
        else:
            self.add_error('Invalid action: %s' % action)
            plist = []
            for p in Person.all():
                p.p_updated = eastern_time(p.p_updated)
                plist.append(p)
            template_values = {
                'action': 'list',
                'errors': self.get_errors(),
                'plist': plist,
                }
            template = jinja_environment.get_template('person.html')
            self.response.out.write(template.render(template_values))

    # ----------------------------------------------------------------------
    def get_domain(self):
        spath = self.request.path.split('/')
        domain = spath.pop(1)
        return domain
    
    # ----------------------------------------------------------------------
    def get_action(self):
        spath = self.request.path.split('/')
        domain = spath.pop(1)
        try:
            action = spath.pop(1)
        except:
            action = 'list'
        if action == '':
            action = 'list'
        return action
    
    # ----------------------------------------------------------------------
    def get_cache(self):
        rval = {'fname': '', 'lname': '', 'phone': '',
                'email': '', 'gname': '', 'roles': []}
        try:
            rval = self.cache
        except AttributeError:
            pid = self.request.get('id')
            if pid != '':
                p = Person.get_by_id(int(pid))
                rval = {'fname': p.p_firstname,
                        'lname': p.p_lastname,
                        'phone': p.p_phone,
                        'email': p.p_email,
                        'gname': p.p_username,
                        'roles': p.p_role}
        return rval

    # ----------------------------------------------------------------------
    def post(self):
        action = self.request.get('action')
        if self.request.get('submit') == "Cancel":
            self.redirect("/person")
            return

        self.cache = {}
        for field in ['fname', 'lname', 'phone', 'email', 'gname', 'roles']:
            self.cache[field] = self.request.get(field)
            logging.info("PersonPage.post - caching '%s' = '%s'" %
                         (field, self.cache[field]))

        # Don't validate fields for a delete request since we're just
        # deleting the record
        if action != 'delete':
            if ' ' in self.request.get('fname'):
                self.add_error('First name may not contain spaces')
            if ' ' in self.request.get('lname'):
                self.add_error('Last name may not contain spaces')
            if not self.valid_phone_number(self.request.get('phone')):
                self.add_error('Phone number is not valid')
            if not self.valid_email_address(self.request.get('email')):
                self.add_error('Email address is not valid')

        if 0 < len(self.get_errors()):
            self.get()
        elif action == 'new':
            p = Person()
            p.p_updater = users.get_current_user()
            p.p_updated = datetime.now()
            p.p_firstname = self.request.get('fname')
            p.p_lastname = self.request.get('lname')
            p.p_phone = self.request.get('phone')
            p.p_email = self.request.get('email')
            p.p_username = self.request.get('gname')
            p.p_role = self.request.get_all('roles')
            logging.info('p_role = %s' % p.p_role)
            p.put()
            self.redirect("/person")
        elif action == 'update':
            person_id = self.request.get('id')
            p = Person.get_by_id(int(person_id))
            p.p_updater = users.get_current_user()
            p.p_updated = datetime.now()
            p.p_firstname = self.request.get('fname')
            p.p_lastname = self.request.get('lname')
            p.p_phone = self.request.get('phone')
            p.p_email = self.request.get('email')
            p.p_username = self.request.get('gname')
            p.p_role = self.request.get_all('roles')
            p.put()
            self.redirect("/person")
        elif action == 'delete':
            person_id = self.request.get('id')
            p = Person.get_by_id(int(person_id))
            p.delete()
            self.redirect("/person/list")
        else:
            self.redirect("/person")
            
    # ----------------------------------------------------------------------
    def valid_phone_number(self, phone):
        if re.match(r'\d{3}[-.]\d{3}[-.]\d{4}$', phone.strip()):
            return True
        else:
            return False
        
    # ----------------------------------------------------------------------
    def valid_email_address(self, email):
        if re.match(r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+$', email.strip()):
            return True
        else:
            return False
        
